package bancosys.tec.rtm.impl.diagnostician;

import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.PortUnreachableException;
import java.net.ServerSocket;
import java.net.SocketException;

import bancosys.tec.rtm.diagnostician.AbstractDiagnostician;
import bancosys.tec.rtm.diagnostician.DiagnosisBean;

/**
 * Diacnosticador que detecta se a VM tem acesso a um stack IPV6.
 * 
 * @author Gustavo Almeida
 */
public class Ipv6StackDiagnostician extends AbstractDiagnostician {
    private static final int PORTA_PARA_TESTE = 2046;

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return "IPv6";
    }

    /**
     * {@inheritDoc}
     */
    protected boolean fillDiagnosisBean(DiagnosisBean bean) throws Exception {
        Boolean ipv6Enabled = Boolean.TRUE;
        Throwable t = null;
        try {
            InetAddress loopback = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 });
            new ServerSocket(PORTA_PARA_TESTE, 0, loopback).close();
        } catch (java.net.UnknownHostException e) {
            ipv6Enabled = null;
            t = e;
        } catch (BindException e) {
            ipv6Enabled = Boolean.TRUE;
            t = e;
        } catch (PortUnreachableException e) {
            ipv6Enabled = Boolean.TRUE;
            t = e;
        } catch (SocketException e) {
            if (e.getClass() == SocketException.class) {
                ipv6Enabled = Boolean.FALSE;
            } else {
                ipv6Enabled = null;
            }
            t = e;
        } catch (IOException e) {
            ipv6Enabled = Boolean.TRUE;
            t = e;
        } catch (Throwable e) {
            ipv6Enabled = null;
            t = e;
        }

        if (ipv6Enabled == null) {
            StringBuilder sb = new StringBuilder("Não foi possível determinar o estado do IPv6");
            if (t != null) {
                sb.append(": ").append(t.getMessage());
            }
            bean.addDescription(sb.toString());
            return false;
        } else if (ipv6Enabled.booleanValue()) {
            StringBuilder sb = new StringBuilder("IPv6 ativo");
            if (t != null) {
                sb.append(": ").append(t.getMessage());
            }
            bean.addDescription(sb.toString());
            return true;
        } else {
            StringBuilder sb = new StringBuilder("IPv6 inativo");
            if (t != null) {
                sb.append(": ").append(t.getMessage());
            }
            bean.addDescription(sb.toString());
            return false;
        }
    }
}